package com.yaoyanshe.trialfield.network.interceptor

import android.util.Log
import okhttp3.*
import okhttp3.ResponseBody.Companion.toResponseBody
import okio.Buffer
import java.nio.charset.Charset
import java.util.*
import java.util.concurrent.TimeUnit

/**
 *<p>description:</p>
 *<p>created on: 2020/9/21 15:30</p>
 * @author tck
 * @version v1.3.0
 *
 */

class SytLoggingInterceptor : Interceptor {

    companion object {
        const val TAG = "tck6666"
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        val original: Request = chain.request()
        getRequestHeaders(original)


        //执行请求，计算请求时间
        val startNs = System.nanoTime()
        val response = try {
            chain.proceed(original)
        } catch (e: Exception) {
            log("<-- HTTP FAILED: $e")
            throw e
        }
        val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)

        return logForResponse(response, tookMs)
    }

    private fun logForResponse(response: Response, tookMs: Long): Response {
        val newBuilder = response.newBuilder()
        val clone = newBuilder.build()
        val body = clone.body
        try {
            log("<-- " + clone.code + ' ' + clone.message + ' ' + clone.request.url + " (" + tookMs + "ms）")

            clone.headers.forEach {
                log("${it.first}: ${it.second}")
            }
            body?.let {
                body.contentType()?.let {
                    if (isPlaintext(it)) {
                        val bytes = body.bytes()
                        val json = String(bytes, Charset.forName("UTF-8"))
                        log("body:$json")

                        return response.newBuilder().body(bytes.toResponseBody(body.contentType())).build()
                    }
                }
            }

        } catch (e: Exception) {
        } finally {
            log("<-- END HTTP")
        }

        return response
    }


    /**
     * 打印请求头
     *
     * @param request 请求的对象
     */
    private fun getRequestHeaders(request: Request) {
        log("${request.method}:${request.url}")

        request.headers.forEach {
            log(it.first + ":" + it.second)
        }
        request.body?.let {
            log("Content-Length: ${it.contentLength()}")
        }

        request.body?.let {
            it.contentType()?.let { mediaType ->
                if (isPlaintext(mediaType)) {
                    bodyToString(request)
                }
            }
        }
    }

    private fun log(msg: String? = "") {
        if (!msg.isNullOrEmpty()) {
            Log.i(TAG, msg)
        }

    }


    private fun bodyToString(request: Request) {
        try {
            val copy = request.newBuilder().build()
            val body = copy.body ?: return
            val buffer = Buffer()
            body.writeTo(buffer)
            log("body:" + buffer.readString(Charset.forName("UTF-8")))
        } catch (e: Exception) {

        }
    }

    private fun isPlaintext(mediaType: MediaType): Boolean {
        if (mediaType.type == "text") {
            return true
        }
        var subtype = mediaType.subtype
        subtype = subtype.toLowerCase(Locale.ROOT)
        if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
            return true
        return false
    }
}